<?php
declare (strict_types=1);

namespace app\admin\service\base;

use app\admin\model\base\Admin;
use app\admin\model\base\AdminMenu;
use app\admin\model\base\AdminRole;
use app\admin\model\base\AdminRoleAccess;
use app\admin\validates\MenuValidate;
use app\admin\validates\RoleValidate;
use app\BaseService;
use auth\Auth;
use think\exception\ValidateException;
use think\response\Json;

/**
 * 菜单管理服务层
 */
class MenuService extends BaseService
{
    /**
     * 获取菜单目录
     * @return Json
     */
    public function authRouters(): Json
    {
        $admin_id = WS_ADMIN_ID;
        //超级管理员显示所有菜单
        if ($admin_id != 1) {
            //获取对应的角色
            $Auth = new Auth();
            $roles = $Auth->getRoles($admin_id);
            //保存用户所属用户组设置的所有权限规则id
            $ids = [];
            foreach ($roles as $g) {
                $ids = array_merge($ids, explode(',', trim($g['menu_ids'], ',')));
            }
            $ids = array_unique($ids);
            if (!$ids) {
                return jsonReturn(0, []);
            }
            $ids = array_map('intval', $ids);
            $where[] = ['id', 'in', $ids];
        }
        //查询数据库
        $field = "*";
        $where[] = ['status', '=', 1];
        $where[] = ['closed', '=', 0];
        $where[] = ['menu_type', 'in', ['M', 'C']];
        $menu = AdminMenu::getList($where, $field);
        //循环
        $temp = [];
        foreach ($menu as $v) {
            $temp[] = [
                'id' => $v['id'],
                'parent_id' => $v['parent_id'],
                'name' => $v['path'],
                'path' => ($v['parent_id'] == 0 ? '/' : '') . $v['path'],
                'hidden' => !$v['visible'],
                'redirect' => 'noRedirect',
                'component' => $v['component'],
                'alwaysShow' => $v['parent_id'] == 0,
                'meta' => [
                    'title' => $v['menu_name'],
                    'icon' => $v['icon'],
                    'link' => null,
                    'noCache' => false,
                ]
            ];
        }
        //无限极分类
        $temp = getMultilevelTree($temp, 0, 'id', 'parent_id', 'children');
        return jsonReturn(1, $temp);
    }

    /**
     * 菜单管理树状图
     * @param int $role_id
     * @return Json
     */
    public function menuTree(int $role_id): Json
    {
        $data['checkedKeys'] = [];
        //获取当前角色所选择的菜单
        $menu_ids = AdminRole::where(['id' => $role_id])->value('menu_ids');
        if ($menu_ids) {
            $menu_ids_arr = explode(",", $menu_ids);
            $data['checkedKeys'] = array_map('intval', $menu_ids_arr);
        }
        //查询数据库
        $where = ['closed' => 0];
        $menus = AdminMenu::getList($where, 'id,parent_id,menu_name as label');
        //无限极分类
        $data['menus'] = getMultilevelTree($menus, 0, 'id', 'parent_id', 'children');
        return jsonReturn(1, $data);
    }

    /**
     * 菜单管理列表
     * @return Json
     */
    public function menuList(): Json
    {
        //查询数据库
        $where = ['closed' => 0];
        $data = AdminMenu::getList($where);
        return jsonReturn(1, $data);
    }

    /**
     * 菜单管理添加
     * @param array $params
     * @return Json
     */
    public function menuAdd(array $params): Json
    {
        //判断菜单类型
        switch ($params['menu_type']) {
            case 'M'://目录
                $scene = 'add_m';
                break;
            case 'C'://菜单
                $scene = 'add_c';
                break;
            case 'F'://按钮
                $scene = 'add_f';
                break;
            default:
                return jsonReturn(0, []);
        }
        //数据验证
        try {
            validate(MenuValidate::class)->scene($scene)->check($params);
        } catch (ValidateException $e) {
            // 验证失败 输出错误信息
            return jsonReturn(0, [], $e->getError());
        }
        //获取排序值
        if ($params['orderby'] <= 0) {
            $Menu = new AdminMenu();
            $params['orderby'] = AdminMenu::setOrderBy($Menu, []);
        }
        //处理参数
        $params['create_time'] = time();
        $params['update_time'] = time();
        $id = AdminMenu::insertGetId($params);
        if ($id) {
            return jsonReturn(1, [], '添加成功');
        }
        return jsonReturn(0, [], '添加失败');
    }

    /**
     * 菜单管理编辑
     * @param array $params
     * @return Json
     */
    public function menuEdit(array $params): Json
    {
        //判断菜单类型
        switch ($params['menu_type']) {
            case 'M'://目录
                $scene = 'edit_m';
                break;
            case 'C'://菜单
                $scene = 'edit_c';
                break;
            case 'F'://按钮
                $scene = 'edit_f';
                break;
            default:
                return jsonReturn(0, []);
        }
        //数据验证
        try {
            validate(MenuValidate::class)->scene($scene)->check($params);
        } catch (ValidateException $e) {
            // 验证失败 输出错误信息
            return jsonReturn(0, [], $e->getError());
        }
        //判断当前菜单是否存在
        $where = ['id' => $params['id'], 'closed' => 0];
        $Model = AdminMenu::where($where)->find();
        if (!$Model) {
            return jsonReturn(0, [], '菜单不存在');
        }
        //设置排序值
        if ($Model->orderby != $params['orderby']) {
            AdminMenu::setOrderBy($Model, [], $params['orderby']);
        }
        //处理参数
        $params['update_time'] = time();
        $id = $Model->save($params);
        if ($id) {
            return jsonReturn(1, [], '编辑成功');
        }
        return jsonReturn(0, [], '编辑失败');
    }

    /**
     * 菜单管理删除
     * @param array $params
     * @return Json
     */
    public function menuDel(array $params): Json
    {
        //查询当前id是否存在
        $Model = AdminMenu::where(['id' => $params['id'], 'closed' => 0])->find();
        if (!$Model) {
            return jsonReturn(0, [], '菜单不存在');
        }
        //判断是否存在下级
        $res = AdminMenu::where(['parent_id' => $params['id'], 'closed' => 0])->value('id');
        if ($res) {
            return jsonReturn(0, [], '存在下级菜单,不能删除');
        }
        //删除
        $res = $Model->delete();
        if ($res) {
            return jsonReturn(1, [], '删除成功');
        }
        return jsonReturn(0, [], '删除失败');
    }

    /**************************** 角色管理 ********************************/
    /**
     * 角色管理列表
     * @param array $params
     * @return Json
     */
    public function roleList(array $params): Json
    {
        $where[] = ['closed', '=', 0];
        //搜索角色名称
        if ($params['role_name']) {
            $where[] = ['role_name', 'like', '%' . $params['role_name'] . '%'];
        }
        //搜索权限字符
        if ($params['role_key']) {
            $where[] = ['role_key', 'like', '%' . $params['role_key'] . '%'];
        }
        //搜索状态
        if (isset($params['status']) && in_array($params['status'], [0, 1])) {
            $where[] = ['status', '=', $params['status']];
        }
        //创建时间筛选
        if ($params['start_time'] && $params['end_time']) {
            $start_time = (int)$params['start_time'];
            $end_time = (int)$params['end_time'];
            $where[] = ['create_time', 'between', [$start_time, $end_time]];
        }
        //获取列表
        $data = AdminRole::getList($where, $params['page'], $params['limit'], 'orderby asc');
        return jsonReturn(1, $data);
    }

    /**
     * 角色管理全部列表
     * @param array $params
     * @return Json
     */
    public function roleListAll(array $params): Json
    {
        $where[] = ['closed', '=', 0];
        //搜索角色名称
        if ($params['role_name']) {
            $where[] = ['role_name', 'like', '%' . $params['role_name'] . '%'];
        }
        //获取列表
        $data = AdminRole::getListAll($where, 'orderby asc');
        return jsonReturn(1, $data);
    }

    /**
     * 角色管理添加
     * @param array $params
     * @return Json
     */
    public function roleAdd(array $params): Json
    {
        //数据验证
        try {
            validate(RoleValidate::class)->scene('add')->check($params);
        } catch (ValidateException $e) {
            // 验证失败 输出错误信息
            return jsonReturn(0, [], $e->getError());
        }
        //获取排序值
        if ($params['orderby'] <= 0) {
            $Role = new AdminRole();
            $params['orderby'] = AdminRole::setOrderBy($Role, []);
        }
        //判断角色名是否存在
        $where = ['role_name' => $params['role_name'], 'closed' => 0];
        $res = AdminRole::findOne($where);
        if ($res) {
            return jsonReturn(0, [], '角色名称重复');
        }
        //处理参数
        $params['menu_ids'] = implode(',', $params['menu_ids']);
        $params['create_time'] = time();
        $params['update_time'] = time();
        $id = AdminRole::insertGetId($params);
        if ($id) {
            return jsonReturn(1, [], '添加成功');
        }
        return jsonReturn(0, [], '添加失败');
    }

    /**
     * 角色管理编辑
     * @param array $params
     * @return Json
     */
    public function roleEdit(array $params): Json
    {
        //数据验证
        try {
            validate(RoleValidate::class)->scene('edit')->check($params);
        } catch (ValidateException $e) {
            // 验证失败 输出错误信息
            return jsonReturn(0, [], $e->getError());
        }
        //判断当前角色是否存在
        $where = ['id' => $params['id'], 'closed' => 0];
        $Model = AdminRole::where($where)->find();
        if (!$Model) {
            return jsonReturn(0, [], '角色不存在');
        }
        //设置排序值
        if ($Model->orderby != $params['orderby']) {
            AdminRole::setOrderBy($Model, [], $params['orderby']);
        }
        //处理参数
        $params['menu_ids'] = implode(',', $params['menu_ids']);
        $params['update_time'] = time();
        $id = $Model->save($params);
        if ($id) {
            return jsonReturn(1, [], '编辑成功');
        }
        return jsonReturn(0, [], '编辑失败');
    }

    /**
     * 角色管理删除
     * @param array $params
     * @return Json
     */
    public function roleDel(array $params): Json
    {
        $id = $params['id'];
        //查询当前id是否存在
        $Model = AdminRole::where(['id' => $id, 'closed' => 0])->find();
        if (!$Model) {
            return jsonReturn(0, [], '角色不存在');
        }
        //删除
        $res = $Model->delete();
        if ($res) {
            AdminRoleAccess::deleteData(['role_id' => $id], true);
            return jsonReturn(1, [], '删除成功');
        }
        return jsonReturn(0, [], '删除失败');
    }

    /**
     * 角色管理状态
     * @param int $id
     * @param int $status
     * @return Json
     */
    public function roleStatus(int $id, int $status): Json
    {
        //判断参数
        if (!in_array($status, [0, 1])) {
            return jsonReturn(0, [], '参数错误');
        }
        //查询管理员
        $Model = AdminRole::where(['id' => $id, 'closed' => 0])->find();
        if (!$Model) {
            return jsonReturn(0, [], '角色不存在');
        }
        //编辑
        $params['status'] = $status;
        $params['update_time'] = time();
        $res = $Model->save($params);
        if ($res) {
            return jsonReturn(1, []);
        }
        return jsonReturn(0, [], '操作失败');
    }

    /**************************** 角色分配用户管理 ***********************/
    /**
     * 角色已分配用户列表
     * @param array $params
     * @return Json
     */
    public function roleAssignedList(array $params): Json
    {
        $where[] = ['b.closed', '=', 0];
        //搜索名称
        if ($params['name']) {
            $where[] = ['b.name', 'like', '%' . $params['name'] . '%'];
        }
        //搜索手机号
        if ($params['phone']) {
            $where[] = ['b.phone', 'like', '%' . $params['phone'] . '%'];
        }
        //判断当前角色ID是否存在
        $res = AdminRole::findOne(['id' => $params['id'], 'closed' => 0]);
        if (!$res) {
            return jsonReturn(0, [], '角色不存在');
        }
        //角色条件
        $where[] = ['a.role_id', '=', $params['id']];
        //获取列表
        $data = AdminRoleAccess::roleAssignedList($where, $params['page'], $params['limit']);
        return jsonReturn(1, $data);
    }

    /**
     * 角色未分配用户列表
     * @param array $params
     * @return Json
     */
    public function roleUnassignedList(array $params): Json
    {
        //搜索名称
        if ($params['name']) {
            $where[] = ['name', 'like', '%' . $params['name'] . '%'];
        }
        //搜索手机号
        if ($params['phone']) {
            $where[] = ['phone', 'like', '%' . $params['phone'] . '%'];
        }
        //判断当前角色ID是否存在
        $res = AdminRole::findOne(['id' => $params['id'], 'closed' => 0]);
        if (!$res) {
            return jsonReturn(0, [], '角色不存在');
        }
        //获取当前角色所有绑定的用户id
        $admin_ids = AdminRoleAccess::where(['role_id' => $params['id']])->column('admin_id');
        $where[] = ['id', 'not in', $admin_ids];
        $where[] = ['closed', '=', 0];
        $list = Admin::getList($where, $params['page'], $params['limit']);
        return jsonReturn(1, $list);
    }

    /**
     * 角色未分配用户授权
     * @param array $params
     * @return Json
     */
    public function roleAuthorization(array $params): Json
    {
        //判断当前角色ID是否存在
        $res = AdminRole::findOne(['id' => $params['id'], 'closed' => 0]);
        if (!$res) {
            return jsonReturn(0, [], '角色不存在');
        }
        //查找管理员ID
        $where[] = ['id', 'in', $params['admin_ids']];
        $where[] = ['closed', '=', 0];
        $admin_list = Admin::where($where)->column('id');
        if (!$admin_list) {
            return jsonReturn(0, [], '管理员不存在');
        }
        //删除原数据
        $where2[] = ['role_id', '=', $params['id']];
        $where2[] = ['admin_id', 'in', $admin_list];
        AdminRoleAccess::deleteData($where2, true);
        //组装新数据
        $data = [];
        foreach ($admin_list as $v) {
            $data[] = ['admin_id' => $v, 'role_id' => $params['id']];
        }
        //写入数据库
        AdminRoleAccess::insertAll($data);
        return jsonReturn(1, []);
    }

    /**
     * 角色已分配用户取消授权
     * @param array $params
     * @return Json
     */
    public function roleUnAuthorization(array $params): Json
    {
        //判断当前角色ID是否存在
        $res = AdminRole::findOne(['id' => $params['id'], 'closed' => 0]);
        if (!$res) {
            return jsonReturn(0, [], '角色不存在');
        }
        //删除数据
        $where2[] = ['role_id', '=', $params['id']];
        $where2[] = ['admin_id', 'in', $params['admin_ids']];
        AdminRoleAccess::deleteData($where2, true);
        return jsonReturn(1, []);
    }


}
